package com.jwgf.smarowindingmachine_unity.ui;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.jwgf.adapter.MultiItemTypeAdapter;
import com.jwgf.common.AppContext;
import com.jwgf.common.ViewCache;
import com.jwgf.itemviewdelegates.StatisticButtonAttr;
import com.jwgf.itemviewdelegates.StatisticButtonDelegate;
import com.jwgf.objectbox.HeadFaultCounter;
import com.jwgf.objectbox.HeadFaultCounter_;
import com.jwgf.objectbox.ObjectBox;
import com.jwgf.objectbox.ShiftReport;
import com.jwgf.report.ShiftTimeRule;
import com.jwgf.smarowindingmachine_unity.R;
import com.jwgf.smarowindingmachine_unity.logic.DatabaseChangedEvent;
import com.jwgf.smarowindingmachine_unity.logic.Report;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.ObservableOnSubscribe;
import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.functions.Function;
import io.reactivex.rxjava3.schedulers.Schedulers;


public class MachineStateMachineStatisticFragment extends BaseFragment {
    public static final String fragmentTag = "MachineStateSpindleStatisticFragment";

    private TextView date;
    private TextView shift_num;
    private TextView operator_tv;
    private TextView shift_team_tv;
    private Button head_btn;
    private Button prev_btn;
    private Button next_btn;
    private Button tail_btn;
    private TextView tvShiftInfoShow;
    private long totalRecord;
    private long currentRecord;

    private RecyclerView recyclerView;
    private MultiItemTypeAdapter adapter;
    private List<StatisticButtonAttr> list;
    private TextView sum;

    private View v;

    private Calendar curDate = Calendar.getInstance();

    private boolean[] buttonStatus = {true, true, false, true};

    private String[] names = {"空管输送带卡管", "回丝箱门未关", "水捻器水量不足", "后1平皮带卡管", "后2平皮带卡管",
            "筒纱电机过热", "游动吹吸风机故障", "空管输送带电机故障", "压缩气压过低", "负压风机变频故障",
            "直流电源故障", "急停", "CBF通讯故障", "纱库通讯故障", "负压变频器通讯故障","直流电源通讯故障",
            "温度保护", "制动电阻", "输入缺相", "检查电流", "过载保护",
            "检查电压", "读取失败"};

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        v = ViewCache.getInstance().getView(R.layout.fragment_machine_state_machine_statistic);
        curDate.setTimeInMillis(Long.valueOf(ShiftTimeRule.getInstance().getCurrentShiftStartTime()));
        initViews();
        rxRefresh(curDate.getTimeInMillis(), "=");
        EventBus.getDefault().register(this);
        return v;
    }

    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        if (hidden) {
            EventBus.getDefault().unregister(this);
        } else {
            rxRefresh(curDate.getTimeInMillis(), "=");
            EventBus.getDefault().register(this);
        }
    }

    private void initViews() {
        date = (TextView) v.findViewById(R.id.date);
        shift_num = (TextView) v.findViewById(R.id.shift_num);
        operator_tv = (TextView) v.findViewById(R.id.operator_tv);
        shift_team_tv = (TextView) v.findViewById(R.id.shiftteam_tv);
        head_btn = (Button) v.findViewById(R.id.head_btn);
        prev_btn = (Button) v.findViewById(R.id.prev_btn);
        next_btn = (Button) v.findViewById(R.id.next_btn);
        tail_btn = (Button) v.findViewById(R.id.tail_btn);
        tvShiftInfoShow = (TextView) v.findViewById(R.id.tv_shift_show);
        currentRecord = Report.getInstance().getShiftCount();
        totalRecord = Report.getInstance().getShiftCount();

        sum = v.findViewById(R.id.sum);

        recyclerView = v.findViewById(R.id.recycler);
        list = new ArrayList<>();
        for (int i = 0; i < names.length; ++i) {
            StatisticButtonAttr attr = new StatisticButtonAttr(names[i], "0");
            list.add(attr);
        }
        adapter = new MultiItemTypeAdapter<>(AppContext.getInstance(), list);
        adapter.addItemViewDelegate(new StatisticButtonDelegate(adapter));
        GridLayoutManager layoutManager = new GridLayoutManager(getActivity(), 6);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setAdapter(adapter);

        HeadFaultCounter counter = ObjectBox.get().boxFor(HeadFaultCounter.class).query()
                .equal(HeadFaultCounter_.start, curDate.getTimeInMillis()).build().findFirst();

        refreshRecyclerView(counter);

        head_btn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                rxRefresh(curDate.getTimeInMillis(), "<<");
            }
        });

        prev_btn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                rxRefresh(curDate.getTimeInMillis(), "<");
            }
        });

        next_btn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                rxRefresh(curDate.getTimeInMillis(), ">");
            }
        });

        tail_btn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                rxRefresh(curDate.getTimeInMillis(), ">>");
            }
        });


    }

    private void setBtnState(boolean isEnable) {
        if (isEnable) {
            head_btn.setEnabled(buttonStatus[0]);
            prev_btn.setEnabled(buttonStatus[1]);
            next_btn.setEnabled(buttonStatus[2]);
            tail_btn.setEnabled(buttonStatus[3]);
        } else {
            head_btn.setEnabled(false);
            prev_btn.setEnabled(false);
            next_btn.setEnabled(false);
            tail_btn.setEnabled(false);
        }
    }

    private void rxRefresh(long time, String flag) {
        setBtnState(false);
        Observable<HeadFaultCounter> observable = Observable.create((ObservableOnSubscribe<ShiftReport>) emitter -> {
            long sqlTime = Report.getInstance().getTime(time, flag);
            ShiftReport basicInfo = Report.getInstance().getBasicInfo(sqlTime);
            totalRecord = Report.getInstance().getShiftCount();
            switch (flag) {
                case "<<":
                    currentRecord = 1;
                    break;
                case "<":
                    if (currentRecord > 1)
                        --currentRecord;
                    break;
                case ">":
                    if (currentRecord < totalRecord)
                        ++currentRecord;
                    break;
                case ">>":
                    currentRecord = totalRecord;
                    break;
            }
            emitter.onNext(basicInfo);
            emitter.onComplete();
        })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .map((Function<ShiftReport, Long>) shiftReport -> {
                    refreshBasicUI(shiftReport);
                    return shiftReport.start;
                })
                .observeOn(Schedulers.io())
                .map((Function<Long, HeadFaultCounter>) aLong -> {
                    HeadFaultCounter counter = ObjectBox.get().boxFor(HeadFaultCounter.class)
                            .query().equal(HeadFaultCounter_.start, aLong).build().findFirst();
                    return counter;
                })
                .observeOn(AndroidSchedulers.mainThread());

        Observer<HeadFaultCounter> observer = new Observer<HeadFaultCounter>() {
            private Disposable d;

            @Override
            public void onSubscribe(Disposable d) {
                this.d = d;
            }

            @Override
            public void onNext(HeadFaultCounter counter) {
                refreshRecyclerView(counter);
                setBtnState(true);
            }

            @Override
            public void onError(Throwable e) {
                refreshRecyclerView(null);
                setBtnState(true);
                d.dispose();
            }

            @Override
            public void onComplete() {
                d.dispose();
            }
        };
        observable.subscribe(observer);
    }

    private void refreshBasicUI(ShiftReport shiftReport) {
        curDate.setTimeInMillis(shiftReport.start);
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        String strDate = sf.format(curDate.getTime());
        String num = String.valueOf(shiftReport.shiftNum);
        String strOperator = shiftReport.operator;
        String strShiftTeam = shiftReport.team;
        totalRecord = Report.getInstance().getShiftCount();
        date.setText(strDate);
        shift_num.setText(num + getResources().getString(R.string.ms_shift));
        shift_team_tv.setText(strShiftTeam);
        operator_tv.setText(strOperator);
        tvShiftInfoShow.setText(currentRecord + "/" + totalRecord);

        if (currentRecord == 1) {
            buttonStatus[0] = true;
            buttonStatus[1] = false;
            buttonStatus[2] = true;
            buttonStatus[3] = true;
        } else if (currentRecord == totalRecord) {
            buttonStatus[0] = true;
            buttonStatus[1] = true;
            buttonStatus[2] = false;
            buttonStatus[3] = true;
        } else {
            buttonStatus[0] = true;
            buttonStatus[1] = true;
            buttonStatus[2] = true;
            buttonStatus[3] = true;
        }
    }

    private void refreshRecyclerView(HeadFaultCounter counter) {
        if (counter != null) {
            String[] values = {String.valueOf(counter.counter_252_1), String.valueOf(counter.counter_252_2),
                    String.valueOf(counter.counter_252_4), String.valueOf(counter.counter_252_6),
                    String.valueOf(counter.counter_252_7), String.valueOf(counter.counter_252_8),
                    String.valueOf(counter.counter_252_9), String.valueOf(counter.counter_252_10),
                    String.valueOf(counter.counter_252_11), String.valueOf(counter.counter_252_12),
                    String.valueOf(counter.counter_252_13), String.valueOf(counter.counter_252_14),
                    String.valueOf(counter.counter_254_0), String.valueOf(counter.counter_254_1),
                    String.valueOf(counter.counter_254_2),
                    String.valueOf(counter.counter_254_8), String.valueOf(counter.counter_254_9),
                    String.valueOf(counter.counter_254_10), String.valueOf(counter.counter_254_11),
                    String.valueOf(counter.counter_254_12), String.valueOf(counter.counter_254_13),
                    String.valueOf(counter.counter_254_14), String.valueOf(counter.counter_254_15)};
            for (int i = 0; i < values.length; ++i) {
                list.get(i).setValue(values[i]);
            }
            adapter.notifyDataSetChanged();
            sum.setText(getString(R.string.sum) + ":" + String.valueOf(counter.getTotalCount()));
        } else {
            for (int i = 0; i < names.length; ++i) {
                list.get(i).setValue("0");
            }
            adapter.notifyDataSetChanged();
            sum.setText(getString(R.string.sum) + ":" + "0");
        }

    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onFaultChange(DatabaseChangedEvent.MachineFaultChanged fault) {
        if (curDate.getTimeInMillis() == Long.parseLong(ShiftTimeRule.getInstance().getCurrentShiftStartTime())) {
            HeadFaultCounter counter = ObjectBox.get().boxFor(HeadFaultCounter.class)
                    .query().equal(HeadFaultCounter_.start, curDate.getTimeInMillis()).build().findFirst();
            refreshRecyclerView(counter);
        }
    }


}